package com.str.queue;
public class LinkedQueue implements Queue {
// Queue values are queues whose elements are objects.

// Inner class
  private static class SLLNode {
    Object data;
    SLLNode next;

    SLLNode() {}
    SLLNode(Object obj) { data = obj; }
    SLLNode(Object obj, SLLNode link) {  
      data = obj;
      next = link; 
    }

    public String toString()
    { return data.toString(); }
  }
  
  private SLLNode front, rear;
  private int count;

// Constructor ...
  public LinkedQueue() { clear(); }

// Modifiers ...
  public final void clear() {
    front = rear = null;
    count = 0;
  }
 
  public void enqueue(Object val) {
  // Add val as the rear element of this queue.
    SLLNode temp = new SLLNode(val, null);
    if (rear == null) 
      front = temp;
    else
      rear.next = temp;
    rear = temp;
    count++;
  }

  public Object dequeue() {
  // Remove and return the front element from this queue,
  // or return null if this queue is empty.
    if (count == 0) 
      throw new IllegalStateException();
    Object val = front.data;
    front = front.next;
    if (front == null) rear = null;
    count--;
    return val;           
  }

// Accessors
  public boolean isEmpty() {
  // Return true if and only if this queue is empty.
    return count == 0;
  }

  public int size() {
  // Return this queue's length.
    return count;
  }
  
  public Object peek() {
  // Return the element at the front of this queue,
  // or null if this queue is empty.
    if (count == 0)
      throw new IllegalStateException();
    return front.data;
  }
  
  // Returns a string representation of the queue
  public String toString() {
    String buf = new String("[ ");
    for (SLLNode curr = front; curr != null; curr = curr.next) {            
      if (curr != front) buf += ", ";
      buf += curr.data.toString();
    }
    buf += " ]";
    return buf;
  }
}
